#include "../Include/LogWriter.h"
#include <fstream>
#include <filesystem>

IMPLEMENT_UNMANED_SINGLETON_X(CLogWriter)


CByteArray::CByteArray()
{

}

CByteArray::~CByteArray()
{

}

////////////////////////////////////////////////////////////////////


CLogWriter::CLogWriter()
{
	m_bIsRunning = true;
	m_writeFileloopQueue.Create(100);
	m_writeRemoteloopQueue.Create(100);
	m_pWriteFileThread = nullptr;
	m_pWriteRemoteThread = nullptr;
}

CLogWriter::~CLogWriter()
{
	m_bIsRunning = false;
	if (m_pWriteFileThread)
	{
		if (m_pWriteFileThread->joinable())
		{
			m_pWriteFileThread->join();
		}
	}

	if (m_pWriteRemoteThread)
	{
		if (m_pWriteRemoteThread->joinable())
		{
			m_pWriteRemoteThread->join();
		}
	}
}

bool CLogWriter::WriteLog(const CByteArray& rByteArray)
{
	bool bRet = m_writeFileloopQueue.EnQueue(rByteArray);
	if (!bRet)
	{
		return false;
	}
	bRet = m_writeRemoteloopQueue.EnQueue(rByteArray);
	if (!bRet)
	{
		return false;
	}
	return true;
}

void CLogWriter::SetRunning(bool bIsRunning)
{
	m_bIsRunning = bIsRunning;
}

bool CLogWriter::IsRunning() const
{
	return m_bIsRunning;
}

void CLogWriter::StartWriteFileThread()
{
	m_pWriteFileThread = std::make_unique<std::thread>(&CLogWriter::WriteFileThreadFunc, this);
}

void CLogWriter::StartWriteRemoteThread()
{
	m_pWriteRemoteThread = std::make_unique<std::thread>(&CLogWriter::WriteRemoteThreadFunc, this);
}

void CLogWriter::WriteFileThreadFunc(CLogWriter* pLogWriter)
{
	while (pLogWriter->IsRunning())
	{
		if(pLogWriter->m_writeFileloopQueue.GetSize() <= 0)
		{
			std::this_thread::sleep_for(std::chrono::milliseconds(10));
			continue;
		}

		CByteArray byteArray;
		if(!pLogWriter->m_writeFileloopQueue.DeQueue(byteArray))
		{
			continue;
		}

		if (!CLogSystem::Instance().IsSaveToFile())
		{
			continue;
		}

		std::string strFileName = CLogSystem::Instance().GetFileName();

		if (std::filesystem::exists(strFileName))
		{
			auto fileSize = std::filesystem::file_size(strFileName);;
			if (fileSize > CLogSystem::Instance().GetDivideSize())
			{
				std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
				std::time_t   now_time_t = std::chrono::system_clock::to_time_t(now);
				std::tm now_tm{};
				localtime_s(&now_tm, &now_time_t);
				char szTime[16] = { 0 };
				strftime(szTime, sizeof(szTime), "_%Y%m%d%H%M%S", &now_tm);
				std::string strNewFileName = strFileName + std::string(szTime);
				std::filesystem::rename(strFileName, strNewFileName);
			}
		}

		std::ofstream file(strFileName, std::ios::app);

		if (!file.is_open())
		{
			pLogWriter->SetRunning(false);
			break;
		}

		file << byteArray.m_strMsg;
	}
}

void CLogWriter::WriteRemoteThreadFunc(CLogWriter* pLogWriter)
{
	while (pLogWriter->IsRunning())
	{

	}
}
